using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
using Andrewl.XnaHelpers.Audio;
using Andrewl.XnaHelpers.Input;
using Andrewl.XnaHelpers.Storage;
using Microsoft.Xna.Framework.Storage;
using Andrewl.XnaHelpers.Generics;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Net;
using System.Threading;
using System.Globalization;

namespace Andrewl.XnaHelpers.GamerServices
{
    public class GamertagHelper
    {
        #region Variable Declarations

        public PlayerIndex? pIndex = null;
        
        public bool done;

        public Gamer gamer;

        public GamerProfile profile;

        public Action gamerCompleteAction = null;

        public Action profileCompleteAction = null;

        private GamerProfile profileCallback;

        public bool isGuest;

        public bool isXboxLive;

        public GamerPresence presence;

        public GamerPrivileges privileges;

        #endregion

        #region Accessors
        
        public bool Done
        { get { return done; } }

        public Gamer Gamer
        { get { return gamer; } }

        public GamerProfile Profile
        { get { return profile; } }

        public string Gamertag
        { get { return gamer.Gamertag; } }

        public Texture2D GamerPicture
        { get { return profile.GamerPicture; } }

        public int GamerScore
        { get { return profile.GamerScore; } }

        public GamerZone GamerZone
        { get { return profile.GamerZone; } }

        public string Motto
        { get { return profile.Motto; } }

        public float Reputation
        { get { return profile.Reputation; } }

        public int TitlesPlayed
        { get { return profile.TitlesPlayed; } }

        public int NumberOfAchievements
        { get { return profile.TotalAchievements; } }

        public RegionInfo Region
        { get { return profile.Region; } }

        public GamerPrivileges Privileges
        { get { return privileges; } }

        #endregion

        #region Constructors

        public GamertagHelper(PlayerIndex ControllerIndex, Action gamerCompleteActionArg)
        {
            pIndex = ControllerIndex;
            gamerCompleteAction = gamerCompleteActionArg;
        }

        public GamertagHelper(PlayerIndex ControllerIndex)
        {
            pIndex = ControllerIndex;
        }

        public GamertagHelper()
        { }

        #endregion

        public void Update(bool AutomaticallyObtainProfile)
        {
            if (gamer == null)
            {
                if (Gamer.SignedInGamers[(PlayerIndex)pIndex] != null)
                {
                    gamer = Gamer.SignedInGamers[(PlayerIndex)pIndex];
                    isGuest = Gamer.SignedInGamers[(PlayerIndex)pIndex].IsGuest;
                    isXboxLive = Gamer.SignedInGamers[(PlayerIndex)pIndex].IsSignedInToLive;
                    presence = Gamer.SignedInGamers[(PlayerIndex)pIndex].Presence;
                    privileges = Gamer.SignedInGamers[(PlayerIndex)pIndex].Privileges;
                    if (AutomaticallyObtainProfile)
                    {
                        profile = gamer.GetProfile();
                    }
                    gamerCompleteAction.Invoke();
                    done = true;
                }
                else
                    return;
            }
         
        }

        /// <summary>
        /// Warning, using this on a networked gamer will cause the game to hang, sometimes indefinetly. Use AsyncGetProfile instead
        /// </summary> 
        public void GetProfile()
        {
            profile = gamer.GetProfile();
        }
        /// <summary>
        /// Asyncrhonously gets the gamer profile - good for getting Networked gamers profiles
        /// </summary>
        /// <param name="actionArg"></param>
        public void AsyncGetProfile(Action actionArg)
        {
            profileCompleteAction = actionArg;
            gamer.BeginGetProfile(callback, (object)"asyncTag");
        }

        public void AsyncGetProfile()
        {
            profileCompleteAction = null;
            gamer.BeginGetProfile(callback, (object)"asyncTag");
        }

        private void callback(IAsyncResult result)
        {
            profileCallback = gamer.EndGetProfile(result);
            if (profileCallback != null)
            {
                profile = profileCallback;
                if (profileCompleteAction != null)
                {
                    profileCompleteAction.Invoke();
                }
            }
            else
                return;
        }

        public bool IsFriend(Gamer gamer)
        {
            return Gamer.SignedInGamers[(PlayerIndex)pIndex].IsFriend(gamer);
        }

        public bool IsGuest()
        {
            return (Gamer.SignedInGamers[(PlayerIndex)pIndex].IsGuest);
        }

        public bool IsXboxLive()
        {
            return (Gamer.SignedInGamers[(PlayerIndex)pIndex].IsSignedInToLive);
        }

        public int PartySize()
        {
            return Gamer.SignedInGamers[(PlayerIndex)pIndex].PartySize;
        }

        public void SetPresence(GamerPresenceMode value)
        {
            presence.PresenceMode = value;
        }


    }
}